from django.shortcuts import render, get_object_or_404, redirect
from django.core.paginator import Paginator
from django.db.models import Q
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.http import JsonResponse
from django.utils.text import slugify
from django.core.files.storage import default_storage
from django.core.files.base import ContentFile
from django.conf import settings
import json
import markdown
import os
import uuid
from .models import Article, Category, Tag
from .forms import ArticleForm

def article_list(request):
    """文章列表视图"""
    articles = Article.objects.filter(status='published').select_related('author', 'category').prefetch_related('tags')
    
    # 搜索功能
    search_query = request.GET.get('search')
    if search_query:
        articles = articles.filter(
            Q(title__icontains=search_query) |
            Q(content__icontains=search_query) |
            Q(excerpt__icontains=search_query)
        )
    
    # 分类筛选
    category_slug = request.GET.get('category')
    if category_slug:
        articles = articles.filter(category__slug=category_slug)
    
    # 标签筛选
    tag_slug = request.GET.get('tag')
    if tag_slug:
        articles = articles.filter(tags__slug=tag_slug)
    
    # 分页
    paginator = Paginator(articles, 10)  # 每页显示10篇文章
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    
    # 获取所有分类和标签用于侧边栏
    categories = Category.objects.all()
    tags = Tag.objects.all()
    
    context = {
        'page_obj': page_obj,
        'categories': categories,
        'tags': tags,
        'search_query': search_query,
        'current_category': category_slug,
        'current_tag': tag_slug,
    }
    
    return render(request, 'blog/article_list.html', context)

def article_detail(request, slug):
    """文章详情视图"""
    article = get_object_or_404(Article, slug=slug, status='published')
    
    # 增加浏览次数
    article.increment_views()
    
    # 获取相关文章（同分类的其他文章）
    related_articles = Article.objects.filter(
        category=article.category,
        status='published'
    ).exclude(id=article.id)[:3]
    
    # 获取文章的评论
    comments = article.comments.filter(is_approved=True)
    
    context = {
        'article': article,
        'related_articles': related_articles,
        'comments': comments,
    }
    
    return render(request, 'blog/article_detail.html', context)

def category_detail(request, slug):
    """分类详情视图"""
    category = get_object_or_404(Category, slug=slug)
    articles = Article.objects.filter(
        category=category,
        status='published'
    ).select_related('author').prefetch_related('tags')
    
    # 分页
    paginator = Paginator(articles, 10)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    
    context = {
        'category': category,
        'page_obj': page_obj,
    }
    
    return render(request, 'blog/category_detail.html', context)

def tag_detail(request, slug):
    """标签详情视图"""
    tag = get_object_or_404(Tag, slug=slug)
    articles = Article.objects.filter(
        tags=tag,
        status='published'
    ).select_related('author', 'category').prefetch_related('tags')
    
    # 分页
    paginator = Paginator(articles, 10)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    
    context = {
        'tag': tag,
        'page_obj': page_obj,
    }
    
    return render(request, 'blog/tag_detail.html', context)

@login_required
def article_create(request):
    """创建文章视图"""
    if request.method == 'POST':
        form = ArticleForm(request.POST, request.FILES)
        if form.is_valid():
            article = form.save(commit=False)
            article.author = request.user
            # 自动生成slug
            if not article.slug:
                article.slug = slugify(article.title)
            article.save()
            form.save_m2m()  # 保存多对多关系
            messages.success(request, '文章创建成功！')
            return redirect('blog:article_detail', slug=article.slug)
    else:
        form = ArticleForm()
    
    return render(request, 'blog/article_form.html', {
        'form': form,
        'title': '创建文章',
        'action': 'create'
    })

@login_required
def article_edit(request, slug):
    """编辑文章视图"""
    article = get_object_or_404(Article, slug=slug)
    
    # 检查权限：只有作者或管理员可以编辑
    if request.user != article.author and not request.user.is_staff:
        messages.error(request, '您没有权限编辑此文章。')
        return redirect('blog:article_detail', slug=slug)
    
    if request.method == 'POST':
        form = ArticleForm(request.POST, request.FILES, instance=article)
        if form.is_valid():
            article = form.save(commit=False)
            # 如果标题改变了，重新生成slug
            if 'title' in form.changed_data:
                article.slug = slugify(article.title)
            article.save()
            form.save_m2m()
            messages.success(request, '文章更新成功！')
            return redirect('blog:article_detail', slug=article.slug)
    else:
        form = ArticleForm(instance=article)
    
    return render(request, 'blog/article_form.html', {
        'form': form,
        'article': article,
        'title': '编辑文章',
        'action': 'edit'
    })

@login_required
def article_delete(request, slug):
    """删除文章视图"""
    article = get_object_or_404(Article, slug=slug)
    
    # 检查权限：只有作者或管理员可以删除
    if request.user != article.author and not request.user.is_staff:
        messages.error(request, '您没有权限删除此文章。')
        return redirect('blog:article_detail', slug=slug)
    
    if request.method == 'POST':
        article.delete()
        messages.success(request, '文章删除成功！')
        return redirect('blog:article_list')
    
    return render(request, 'blog/article_confirm_delete.html', {
        'article': article
    })

def markdown_preview(request):
    """Markdown预览API"""
    if request.method == 'POST':
        try:
            data = json.loads(request.body)
            content = data.get('content', '')
            
            # 转换Markdown为HTML
            html = markdown.markdown(
                content,
                extensions=[
                    'markdown.extensions.extra',
                    'markdown.extensions.codehilite',
                    'markdown.extensions.toc',
                ]
            )
            
            return JsonResponse({
                'success': True,
                'html': html
            })
        except Exception as e:
            return JsonResponse({
                'success': False,
                'error': str(e)
            })
    
    return JsonResponse({'success': False, 'error': 'Invalid request method'})


@login_required
def upload_image(request):
    """图片上传API"""
    if request.method == 'POST':
        try:
            # 检查是否有文件上传
            if 'image' not in request.FILES:
                return JsonResponse({
                    'success': False,
                    'error': '没有选择文件'
                })
            
            image_file = request.FILES['image']
            
            # 验证文件类型
            allowed_types = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp']
            if image_file.content_type not in allowed_types:
                return JsonResponse({
                    'success': False,
                    'error': '不支持的文件类型，请上传 JPG、PNG、GIF 或 WebP 格式的图片'
                })
            
            # 验证文件大小 (5MB限制)
            max_size = 5 * 1024 * 1024  # 5MB
            if image_file.size > max_size:
                return JsonResponse({
                    'success': False,
                    'error': '文件大小不能超过5MB'
                })
            
            # 生成唯一文件名
            file_extension = os.path.splitext(image_file.name)[1]
            unique_filename = f"{uuid.uuid4()}{file_extension}"
            
            # 创建上传路径
            upload_path = f"blog/images/{unique_filename}"
            
            # 保存文件
            file_path = default_storage.save(upload_path, ContentFile(image_file.read()))
            
            # 生成访问URL
            if hasattr(settings, 'MEDIA_URL'):
                image_url = f"{settings.MEDIA_URL}{file_path}"
            else:
                image_url = f"/media/{file_path}"
            
            return JsonResponse({
                'success': True,
                'url': image_url,
                'filename': unique_filename
            })
            
        except Exception as e:
            return JsonResponse({
                'success': False,
                'error': f'上传失败: {str(e)}'
            })
    
    return JsonResponse({'success': False, 'error': 'Invalid request method'})
